import random
import types

from fastapi import APIRouter
from re_common.baselibrary.tools.all_requests.aiohttp_request import AioHttpRequest
from re_common.baselibrary.tools.all_requests.mrequest import MRequest
from re_common.baselibrary.utils.core.mlamada import bools_string
from re_common.baselibrary.utils.core.requests_core import MsgCode

from apps.allsubdb.cnkijournal.models import headers, DataArticleModel, DataRefModel, DataRefPageModel, DownIssueModel, \
    DownJournalId, DownYearModel, DataCitedPageModel, DownOutlineModel
from apps.core.global_model import MarksModel
from apps.core.m_route import ContextIncludedRoute
from apps.core.return_info import InputInfoModel, ReturnInfo
from apps.crawler_platform.util.requestapihelper import RequestApiHelper

router = APIRouter(route_class=ContextIncludedRoute)

PYKM_LISTS = ['GJZK', 'WDFP', 'GHCX', 'GOGL', 'CXQY', 'XMSH', 'SWSL', 'YNXB', 'GYNP', 'ALYJ', 'ALBL', 'ADFL', 'AHWB',
              'AHWL', 'ADLY', 'BNJZ', 'BBML', 'BXLS', 'BBYJ', 'BDFL', 'BDFX', 'SWMY', 'BDSX', 'BXCP', 'BDZP', 'BDZD',
              'SWBD', 'BFYL', 'BHFP', 'BJRP', 'BJLW', 'MSLC', 'XSJB', 'BJWB', 'WWKG', 'BJZC', 'BLJK', 'BSDF', 'BWFX',
              'BJKG', 'BYFX', 'BIGL', 'JXBJ', 'KWHY', 'BWSW', 'BJZZ', 'BZXY', 'BFLN', 'BGFZ', 'BYXJ', 'BJWN', 'CSFL',
              'CYGC', 'CZJP', 'CJFZ', 'CZQL', 'CAXS', 'CJWH', 'CJWM', 'LRWS', 'CYZP', 'CZWB', 'CQFZ', 'CYJP', 'CXHG',
              'CYFP', 'CDKG', 'CDKY', 'SWGX', 'CQGH', 'CSZI', 'CSSY', 'CXGC', 'CQFL', 'CXCY', 'HZXK', 'CMPL', 'CMGL',
              'CMJY', 'CMYS', 'CTZG', 'KXLW', 'CUWX', 'CTWY', 'CTWJ', 'CTWX', 'CIXU', 'DGJJ', 'DLMZ', 'DLSS', 'DLJD',
              'DALL', 'DDWX', 'DDGA', 'DDMP', 'DDKJ', 'DDRB', 'DARX', 'DSWX', 'DDSY', 'DDWY', 'DDYU', 'DAYH', 'DDZW',
              'DDMZ', 'DMPL', 'DZYB', 'DNFG', 'DXFJ', 'DJWJ', 'DAOJ', 'DQTY', 'DXNW', 'DXWY', 'DAYN', 'DYSU', 'DXZK',
              'DGZX', 'DCGW', 'DEYJ', 'DFPL', 'DSLY', 'DFWY', 'SEIS', 'DIZY', 'DYLJ', 'DBYJ', 'DBYC', 'DFBW', 'DFCK',
              'DFKG', 'DFXZ', 'YYDF', 'DMYJ', 'DNFX', 'DNSF', 'FXDY', 'DYPL', 'DYWY', 'DHYZ', 'DWHJ', 'DWHY', 'DHTL',
              'DHGJ', 'DCGZ', 'DSGZ', 'DSWN', 'DXLC', 'ELSZ', 'ELSP', 'QSJT', 'FDYS', 'FGZX', 'FFLC', 'FLLC', 'FLFF',
              'FFFS', 'FLSK', 'FLZK', 'LAWP', 'FLWY', 'FLLL', 'FLYY', 'FALV', 'FVSP', 'FLSJ', 'FQSP', 'FYIJ', 'FYLT',
              'FYJX', 'FYSC', 'FZLC', 'FSLC', 'FXJY', 'FAJJ', 'FZFS', 'FZHN', 'FZLT', 'FZXD', 'FWWY', 'FIYJ', 'FZWJ',
              'FWHY', 'FDGG', 'FDGJ', 'PFDW', 'FDZZ', 'FHCM', 'FZKG', 'WERE', 'GJCS', 'GJPL', 'JYXS', 'GDRY', 'HSCG',
              'ZYDJ', 'MZDB', 'GXGQ', 'GXXS', 'GCGN', 'GFYJ', 'GGGC', 'GGGY', 'GHCS', 'GZLP', 'GFPL', 'JRGS', 'GSZL',
              'ROID', 'GYJW', 'GHFX', 'GXBW', 'GXWB', 'GZDY', 'GZWB', 'LGTF', 'PZDG', 'GMZM', 'WMGJ', 'GDYO', 'QYPL',
              'GDWE', 'GDXY', 'GGXK', 'GHSL', 'GXYJ', 'GZSJ', 'GJBH', 'AHGJ', 'JLLG', 'GBQY', 'GJGX', 'GJHA', 'JHJK',
              'GJYU', 'GHJY', 'GHXB', 'GUOJ', 'GJJF', 'GMFL', 'GJRU', 'GJRX', 'GSLC', 'WHGL', 'XZPL', 'GJXC', 'GJYM',
              'GJWX', 'GJHH', 'GUZK', 'GJXD', 'MRYJ', 'GOXE', 'GXLH', 'GYJP', 'HDFL', 'KGHD', 'QLWH', 'HGFP', 'HPJJ',
              'HKJK', 'SWHS', 'HFHF', 'HGYL', 'HGXL', 'HZWB', 'HJYH', 'HRYY', 'HYFX', 'HYCB', 'HYDJ', 'YGJJ', 'JXXK',
              'YJHY', 'HYSB', 'HYUS', 'HYHC', 'HZYB', 'HNBY', 'HZWY', 'HDXS', 'HAXS', 'HHWM', 'HHZY', 'HJFL', 'HQWX',
              'HQHR', 'HWWP', 'HXBP', 'HXYU', 'PHXL', 'HYYL', 'HZCB', 'HZGX', 'HZKC', 'HZRW', 'HZXS', 'FBWS', 'HUIX',
              'IFLR', 'HNKG', 'HNBW', 'HNXY', 'SWHJ', 'HXSN', 'JDWL', 'JLSC', 'JGYS', 'JBJB', 'JBYJ', 'JCDY', 'JDXY',
              'JSJP', 'JSWY', 'JSYE', 'GCLS', 'JYLG', 'ZZWH', 'JNZS', 'JZSL', 'JYKL', 'JYLJ', 'ZCGC', 'JYUY', 'JZLL',
              'JDJJ', 'JDWH', 'JDXS', 'JIER', 'HQWY', 'JNAN', 'JDCH', 'JDDB', 'JDSX', 'JCFX', 'JCXS', 'JDFL', 'JGJY',
              'JJDP', 'JJFX', 'JLZC', 'JNSX', 'JJSQ', 'JJTJ', 'JJXF', 'JGZL', 'JJFC', 'JJFL', 'JFYJ', 'JSFP', 'JXWX',
              'JFZP', 'JRFY', 'JRFW', 'JRGY', 'JRKX', 'JKJR', 'JXDS', 'SWJW', 'JYBY', 'JXJS', 'JYAN', 'KFJJ', 'KZSL',
              'KZWH', 'KGXJ', 'KGXY', 'KEBJ', 'KJFP', 'KKDX', 'KEJU', 'ZRKJ', 'KMGZ', 'KUYJ', 'KZXK', 'KWJY', 'KWHL',
              'KJLT', 'KYKP', 'KWHC', 'KWHG', 'KWHJ', 'KYWY', 'LDJY', 'LDJP', 'XKLZ', 'LZGJ', 'LHLS', 'LSJY', 'YJLX',
              'LHYJ', 'LZZL', 'CCGS', 'LJKG', 'LNBW', 'LBXK', 'LUJW', 'LLSX', 'LNXB', 'LJPL', 'LSDL', 'LSFX', 'WXLS',
              'LSWE', 'YJLS', 'LYWX', 'LYYY', 'LJJS', 'LLXS', 'SWLW', 'LLYG', 'LJYJ', 'LJGL', 'LJSY', 'LYKG', 'LSBW',
              'TGHS', 'LYXJ', 'MKLS', 'MKMY', 'MKSW', 'MKSK', 'MKYJ', 'SWMZ', 'MKZY', 'SWMS', 'MXYJ', 'MDFP', 'MZDY',
              'MZSC', 'MWSY', 'MGWT', 'MJPP', 'MSLT', 'MSGU', 'MTJL', 'MXPL', 'MGSY', 'MBLC', 'MWYJ', 'MQLC', 'MQXX',
              'MSCX', 'MHYJ', 'MSYL', 'MING', 'MJNF', 'MSFA', 'MSFL', 'MSDJ', 'MZFP', 'MZYC', 'MZSW', 'MZSY', 'MZXY',
              'CDFP', 'NJFL', 'NDSP', 'NDXJ', 'NYTP', 'NFMZ', 'SWGZ', 'NHDZ', 'NJXY', 'NKFZ', 'NKFL', 'NKRB', 'NKSX',
              'NKYK', 'NXYJ', 'NHYJ', 'OMWX', 'OYXK', 'OFPL', 'PWYJ', 'PTXK', 'QBWJ', 'QLYJ', 'QXSY', 'QCJX', 'QHYS',
              'QBXJ', 'QHFP', 'QHFH', 'QHKX', 'QHSP', 'QXZJ', 'QHZQ', 'QSLC', 'QTQJ', 'QZDZ', 'QIYJ', 'QDLB', 'QWLC',
              'GZYJ', 'QYHG', 'QQZX', 'QQSP', 'QZDY', 'QZWL', 'QQBW', 'QXUE', 'QWXJ', 'RBFY', 'RCYJ', 'RCPY', 'RDFL',
              'RGZN', 'RKSH', 'RWYB', 'HRGP', 'RQYJ', 'WENR', 'RWCK', 'RWLC', 'RWLT', 'RWSJ', 'RWZG', 'RZSX', 'RYJY',
              'NJTS', 'RBWL', 'RYYJ', 'RBXE', 'RYJX', 'SWRJ', 'RUDJ', 'RXPL', 'RXWM', 'RZLT', 'SDKG', 'SJKG', 'SJWC',
              'SXWC', 'SDFP', 'SLKL', 'SHBW', 'SHCY', 'SHGM', 'HJBS', 'LUYJ', 'SHMZ', 'SHWB', 'SXHK', 'SSFI', 'SWWY',
              'SWYY', 'SXBW', 'SXKG', 'LXSX', 'SBYJ', 'SHBB', 'YSGP', 'SHFX', 'JYSS', 'SZFQ', 'SHFP', 'SHUI', 'SHFL',
              'SHEJ', 'CDLP', 'SJFP', 'SJWY', 'SMXL', 'GGRZ', 'STJP', 'SAFZ', 'YJJH', 'SNJI', 'SYBW', 'SQXL', 'SDFU',
              'DYSC', 'SGZZ', 'SJKY', 'SHGE', 'SHWJ', 'SWJY', 'PLWX', 'SJYI', 'SJYH', 'WPJK', 'SJJK', 'SKSY', 'SQYJ',
              'STSA', 'SWXS', 'SYUJ', 'SZSK', 'SZWJ', 'SDBL', 'SWLT', 'SXRC', 'SFPL', 'SHZM', 'JDSJ', 'SUXU', 'SZRW',
              'SZLP', 'SCZA', 'SCDU', 'SIFA', 'SIFF', 'SFGG', 'LSFY', 'SKUX', 'SMQS', 'SIWN', 'SIWE', 'JYTS', 'SDWH',
              'SOYJ', 'STLS', 'SZWB', 'TPYD', 'TWLS', 'TZXS', 'TXYJ', 'TSLC', 'TSSP', 'TTSY', 'TJTL', 'TSPP', 'JBHF',
              'TLLC', 'TSPL', 'TOSJ', 'IVST', 'TDYJ', 'TEQY', 'TJWK', 'WGFS', 'SWWJ', 'WGMX', 'WGJK', 'ZXWG', 'WYJU',
              'WYLC', 'WYJS', 'WLFP', 'WXFY', 'WXEJ', 'BWBJ', 'WHCY', 'WHFL', 'SWWH', 'CDYC', 'WHSX', 'WJXH', 'WWJZ',
              'WWKY', 'WWXF', 'WXYX', 'WXLL', 'WXQY', 'LAAS', 'WPCL', 'WZWW', 'ZCSS', 'WKLR', 'XASH', 'ZWXD', 'DXFL',
              'XCJJ', 'XDSP', 'XDWG', 'XDZW', 'XDWL', 'YJZJ', 'XCGJ', 'XJFP', 'XJQN', 'JYXA', 'XZYZ', 'XBMI', 'XRKX',
              'XBFJ', 'XBKG', 'XBSP', 'XBSM', 'XBLT', 'XSXX', 'XNBM', 'FALN', 'XNFX', 'XNGJ', 'XNXK', 'XNPL', 'XFWT',
              'OFLC', 'FPYJ', 'SSFL', 'XSPJ', 'XSFP', 'XSFQ', 'XGXU', 'XSXY', 'XZFL', 'XJIN', 'XMTY', 'SDDB', 'XSDL',
              'XSJU', 'XSSX', 'XSLK', 'XWCP', 'XWXP', 'XTIB', 'OXQY', 'XSWX', 'XXAX', 'XYLS', 'XBLU', 'XXTN', 'XSCK',
              'XSZG', 'YFYJ', 'YGXK', 'YZLC', 'YHCX', 'KKFY', 'SYTT', 'YCJC', 'DMHZ', 'JSMM', 'YGYJ', 'YMYL', 'YXKX',
              'YNJP', 'YYWX', 'ENYJ', 'YSLS', 'YSXJ', 'YSJK', 'YSLW', 'YYXT', 'YUAD', 'YSMZ', 'YUEF', 'LUFX', 'JYNY',
              'YHXT', 'YLYY', 'YDDQ', 'YHXY', 'YLYF', 'YDFP', 'YWHJ', 'YYCJ', 'YYGH', 'YYLS', 'YULJ', 'YYWH', 'YJJK',
              'YYFL', 'YWHT', 'YYWY', 'YCYJ', 'YXLC', 'YUYA', 'YYZC', 'ZQLZ', 'ZWFJ', 'ZAXK', 'ZQZG', 'ZLGL', 'ZDFP',
              'ZDSK', 'ZJLL', 'YLZJ', 'ZFGP', 'ZFZP', 'ZFZL', 'ZJXL', 'ZQFP', 'ZQFY', 'ZZFX', 'SWQH', 'PEQQ', 'SWZJ',
              'ZZXP', 'ZFPL', 'ZSGL', 'YJZS', 'ZXJL', 'ZXLP', 'ZXTG', 'ZALC', 'ZDJJ', 'ZHCL', 'ZSQY', 'ZSJZ', 'ZSCF',
              'ZSZS', 'ZGPC', 'ZSWX', 'ZEGX', 'ZCFP', 'ZCYJ', 'ZDFX', 'ZDRY', 'ZDWT', 'GCSU', 'ZLLY', 'ZUZG', 'ALFP',
              'JYZT', 'ZBYJ', 'ZBZY', 'ZBJE', 'BOWH', 'BDCY', 'ZCFZ', 'ZGCN', 'CKFP', 'ZGCS', 'ZCMJ', 'ZGCC', 'DAYJ',
              'DWYJ', 'ZDXW', 'WHLC', 'DSBM', 'DZKD', 'DZKC', 'DZLY', 'DZYW', 'ZGET', 'ETWX', 'ZESP', 'XBFY', 'FYZY',
              'FAJY', 'FZJB', 'FZWH', 'PFEY', 'SWFX', 'ZGPL', 'ZKGK', 'GZCF', 'ZGZP', 'GDWC', 'GDFL', 'ZJCK', 'ZGKN',
              'LZJG', 'HYJN', 'HYJP', 'SWSY', 'ZGHL', 'HGFZ', 'HZUX', 'CJZJ', 'JZLH', 'ZGJP', 'JFPL', 'RJJY', 'JJLC',
              'YJPL', 'JYZC', 'SWTQ', 'ZJSP', 'CHJJ', 'JXZM', 'ZJNG', 'ZJRX', 'KXTW', 'ZKJP', 'ZLDJ', 'CLSY', 'ZLYP',
              'YJMS', 'MSZG', 'MTFZ', 'MXZG', 'ZGMX', 'MBJA', 'XCFX', 'CANC', 'QYZG', 'RQPL', 'ZGRX', 'SDMZ', 'ZSFN',
              'SGAQ', 'SWSG', 'ZSKB', 'SWSK', 'WXXK', 'SHLS', 'GSXL', 'CSTT', 'ZSPL', 'SGYJ', 'SGDT', 'ZGPO', 'SXUE',
              'PLZG', 'SKXK', 'ZSSY', 'SWNH', 'CGTC', 'WYUJ', 'WYUY', 'ZWCY', 'ZWGJ', 'WHCP', 'GWLN', 'ZGLG', 'WLZG',
              'WXJK', 'WZZG', 'GWZU', 'WXLC', 'XFNK', 'ZXCJ', 'ZXPL', 'XWCJ', 'XGZG', 'SWZY', 'RWPL', 'CAWD', 'ZYKB',
              'YZXS', 'XBYT', 'YYZV', 'ZYUB', 'ZZBG', 'XXZG', 'ZDBQ', 'ZHIK', 'ZLPL', 'ZBWJ', 'ZCBY', 'ZDME', 'ZSYL',
              'CCOC', 'CCCS', 'ZHXQ', 'ZHYL', 'ZHWH', 'ZMRW', 'ZSFL', 'ZWWH', 'ZWWW', 'ZWWY', 'ZWLT', 'CFLL', 'ZXFL',
              'ZXTS', 'ZYYU', 'SWZW', 'YKJK', 'ZHHC', 'LCZJ', 'XKZZ', 'ZHUZ', 'ZBLJ', 'ZRBW', 'ZYZJ', 'SWHY', 'SWRL',
              'SWZS', 'SWXL', 'ZXMW', 'ZOJY', 'ZJLS', 'ZJYM', 'ZJMZ', 'SWZX', 'YSLY', 'LDZX', 'CXYJ', 'XDXD', 'ZKSF',
              'EYXZ', 'WHXY', 'QLHR', 'WYSG', 'NFPL', 'GZKG', 'GJFL', 'FLJR', 'SXGK', 'OZYW', 'GJFK', 'ZNFL', 'DFZL',
              'SFJL', 'GJQP', 'JYGH', 'ZGCT', 'TYCY', 'QYSJ', 'QDWH', 'YSYD', 'GSLP']


@router.post("/step1/journal_home")
async def journal_home(input: InputInfoModel[MarksModel]):
    """

    marks: lblPageCount
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    url = r'https://navi.cnki.net/knavi/Common/LeftNavi/Journal'
    marks = input.data.marks
    proxy = input.proxy
    form = {
        "productcode": "CJFD",
        "index": "1",
        "random": str(round(random.uniform(0, 1), 16)),
    }
    this_header = headers.copy()
    this_header["Accept"] = "text/plain, */*; q=0.01"
    rrq = RequestApiHelper.get_rrq()
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "data": form,
        "proxy": proxy,
        "moths": MRequest.POST,
        "middler_list": [rrq.status_code_middlerwares, rrq.marks_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.set_url(url).set_data(form) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy).set_header(this_header) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.POST)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html}
    return return_info.todict()


@router.post("/step1/journal_list")
async def journal_list(input: InputInfoModel[DownJournalId]):
    """
    获取期刊列表的信息(在期刊导航页面 选择全部期刊 然后选择右边的列表展示图标)
    marks: lblPageCount
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    url = r'https://navi.cnki.net/KNavi/Common/Search/Journal'
    pageindex = input.data.page  # 第一页为1
    marks = input.data.marks
    proxy = input.proxy
    form = {
        'SearchStateJson': r'{"StateID":"","Platfrom":"","QueryTime":"","Account":"knavi","ClientToken":"","Language":"","CNode":{"PCode":"CJFD","SMode":"","OperateT":""},"QNode":{"SelectT":"","Select_Fields":"","S_DBCodes":"","QGroup":[],"OrderBy":"OTB|desc","GroupBy":"","Additon":""}}',
        'displaymode': '2',
        'pageindex': str(pageindex),
        'pagecount': '20',  # 21(网格模式为21)
        'index': '1',
        'random': '0.18096246145757267'
    }
    # 学科导航 如果不是class 就是全部期刊翻页就可以了
    # input.data.asscii 为 字母A到J对应学科导航的10个大分类
    if input.data.type == "class":
        SearchStateJson = r'{"StateID":"","Platfrom":"","QueryTime":"","Account":"knavi","ClientToken":"","Language":"","CNode":{"PCode":"CJFD","SMode":"","OperateT":""},"QNode":{"SelectT":"","Select_Fields":"","S_DBCodes":"","QGroup":[{"Key":"Navi","Logic":1,"Items":[],"ChildItems":[{"Key":"Journal","Logic":1,"Items":[{"Key":1,"Title":"","Logic":1,"Name":"168专题代码","Operate":"","Value":"%s?","ExtendType":0,"ExtendValue":"","Value2":""}],"ChildItems":[]}]}],"OrderBy":"OTA|DESC","GroupBy":"","Additon":""}}'
        form["SearchStateJson"] = SearchStateJson % input.data.subject
    form['random'] = str(round(random.uniform(0, 1), 16))
    this_header = headers.copy()
    rrq = RequestApiHelper.get_rrq()
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "data": form,
        "proxy": proxy,
        "moths": MRequest.POST,
        "middler_list": [rrq.status_code_middlerwares, rrq.marks_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.set_url(url).set_data(form) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy).set_header(this_header) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.POST)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html}
    return return_info.todict()


@router.post("/step2/down_journal_info")
async def down(input: InputInfoModel[DownYearModel]):
    """
    下载单独的期刊信息
    marks: titbox
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    pykm = input.data.pykm
    marks = input.data.marks
    proxy = input.proxy
    this_header = headers.copy()
    url = r'https://navi.cnki.net/knavi/JournalDetail?pcode=CJFD&pykm=%s' % pykm
    rrq = RequestApiHelper.get_rrq()
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "proxy": proxy,
        "moths": MRequest.POST,
        "middler_list": [rrq.status_code_middlerwares, rrq.marks_middlerwares, rrq.end_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.set_url(url).set_header(this_header) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.POST)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html}
    return return_info.todict()


@router.post("/step5/down_year")
async def down_year(input: InputInfoModel[DownYearModel]):
    """
    下载年列表 可以解析出年和期的信息
    marks: YearIssueTree
    :param input: 
    :return: 
    """
    return_info = ReturnInfo()
    pykm = input.data.pykm
    marks = input.data.marks
    proxy = input.proxy
    this_header = headers.copy()
    this_header['Referer'] = 'https://navi.cnki.net/knavi/JournalDetail?pcode=CJFD&pykm=%s' % pykm
    url = r'https://navi.cnki.net/knavi/JournalDetail/GetJournalYearList?pcode=CJFD&pykm=%s&pIdx=0' % pykm
    rrq = RequestApiHelper.get_rrq()
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "proxy": proxy,
        "moths": MRequest.POST,
        "middler_list": [rrq.status_code_middlerwares, rrq.marks_middlerwares, rrq.end_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.set_url(url).set_header(this_header) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.POST)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html}
    return return_info.todict()


@router.post("/step5/down_getnfalloutline")
async def down_getnfalloutline(input: InputInfoModel[DownOutlineModel]):
    """
    下载网络首发
    marks: clearfix
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    pcode = input.data.pcode
    type = input.data.type
    pageIdx = input.data.pageIdx
    pykm = input.data.pykm
    marks = input.data.marks
    proxy = input.proxy
    url = r'https://navi.cnki.net/knavi/JournalDetail/GetnfAllOutline'
    this_header = headers.copy()
    form = {
        "pykm": pykm,
        "pcode": pcode,
        "pageIdx": pageIdx,
        "type": type,
    }
    rrq = RequestApiHelper.get_rrq()
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "data": form,
        "proxy": proxy,
        "moths": MRequest.POST,
        "middler_list": [rrq.status_code_middlerwares, rrq.marks_middlerwares, rrq.end_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    #
    # rrq.set_url(url).set_params(form) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy).set_header(this_header) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.POST)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html}
    return return_info.todict()


@router.post("/step7/down_issue")
async def down_issue(input: InputInfoModel[DownIssueModel]):
    """
    下载期，下载的结果用于解析文章id
    marks 建议为 "articleCount"
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    pubyear = input.data.pubyear
    num = input.data.num
    pykm = input.data.pykm
    pageIdx = input.data.pageIdx
    marks = input.data.marks
    proxy = input.proxy
    # url = r'https://navi.cnki.net/knavi/JournalDetail/GetArticleList?year=%s&issue=%s&pykm=%s&pageIdx=%s&pcode=CJFD'
    # url = url % (pubyear, num, pykm,str(pageIdx))
    url = r'https://navi.cnki.net/knavi/JournalDetail/GetArticleList'
    form = {
        'year': pubyear,
        'issue': num,
        'pykm': pykm,
        'pageIdx': str(pageIdx),
        'pcode': 'CJFD'
    }
    this_header = headers.copy()
    this_header['Referer'] = 'https://navi.cnki.net/knavi/JournalDetail?pcode=CJFD&pykm={}'.format(pykm)
    this_header['sec-ch-ua'] = '"Chromium";v="88", "Google Chrome";v="88", ";Not A Brand";v="99"'
    rrq = RequestApiHelper.get_rrq()
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "data": form,
        "proxy": proxy,
        "moths": MRequest.POST,
        "middler_list": [rrq.status_code_middlerwares, rrq.marks_middlerwares, rrq.end_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    #
    # rrq.set_url(url).set_params(form) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy).set_header(this_header) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.POST)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html}
    return return_info.todict()


@router.post("/step8/down_article")
async def down_article(input: InputInfoModel[DataArticleModel]):
    """
    下载期刊的国内版元数据信息，为期刊信息服务
    marks 建议为 filename.lower(),'brief'

    :param input:
    :return:
    """
    return_info = ReturnInfo()
    marks = input.data.marks
    proxy = input.proxy
    filename = input.data.filename
    this_header = headers.copy()
    if filename[:4] in PYKM_LISTS:
        dbcode = "CCJD"
    else:
        dbcode = "CJFD"
    knsUrl = r'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=%s&filename=%s' % (dbcode, filename)

    def article_middlerwares(self):
        """
        验证返回码
        :return:
        """
        if self.html.find('所查找的文献不存在') != -1:
            self.resp_dicts["code"] = MsgCode.NO_RESOURCE
            self.resp_dicts["msg"] = "所查找的文献不存在"
            return False, self.resp_dicts
        return True, self.resp_dicts

    rrq = RequestApiHelper.get_rrq()
    rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": knsUrl,
        "timeout": 30,
        "marks": marks,
        "proxy": proxy,
        "moths": MRequest.GET,
        "middler_list": [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares, rrq.marks_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)

    # rrq = AioHttpRequest()
    # rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    # rrq.set_header(this_header).set_url(knsUrl) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.GET)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html}
    return return_info.todict()


@router.post("/step8/down_online")
async def down_article(input: InputInfoModel[DataArticleModel]):
    """
    下载期刊的国内版元数据信息，为期刊信息服务
    marks 建议为 filename.lower(),'brief'

    :param input:
    :return:
    """
    return_info = ReturnInfo()
    marks = input.data.marks
    proxy = input.proxy
    filename = input.data.filename
    this_header = headers.copy()
    this_header["Host"] = "kns.cnki.net"
    this_header["Referer"] = "https://navi.cnki.net/"
    del this_header["Origin"]
    knsUrl = r'https://kns.cnki.net/kcms/detail/%s.html' % filename

    def article_middlerwares(self):
        """
        验证返回码
        :return:
        """
        if self.html.find('所查找的文献不存在') != -1:
            self.resp_dicts["code"] = MsgCode.NO_RESOURCE
            self.resp_dicts["msg"] = "所查找的文献不存在"
            return False, self.resp_dicts
        return True, self.resp_dicts

    rrq = RequestApiHelper.get_rrq()
    rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": knsUrl,
        "timeout": 30,
        "marks": marks,
        "proxy": proxy,
        "moths": MRequest.GET,
        "middler_list": [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares,
                         rrq.marks_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    #
    # rrq.set_header(this_header).set_url(knsUrl) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.GET)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html}
    return return_info.todict()


@router.post("/step8/down_article_oversea")
async def down_article(input: InputInfoModel[DataArticleModel]):
    """
    下载期刊的元数据海外版信息，单独下载不依赖
    marks 建议为 filename.lower(),'container','wx-tit'

    :param input:
    :return:
    """
    return_info = ReturnInfo()
    marks = input.data.marks
    proxy = input.proxy
    filename = input.data.filename
    this_header = headers.copy()
    if filename[:4] in PYKM_LISTS:
        dbcode = "CCJD"
    else:
        dbcode = "CJFD"

    oversea = r'https://oversea.cnki.net/kcms/detail/detail.aspx?dbcode=%s&filename=%s' % (dbcode, filename)

    def article_middlerwares(self):
        """
        验证返回码
        :return:
        """
        if self.html.find('所查找的文件不存在') != -1:
            self.resp_dicts["code"] = MsgCode.NO_RESOURCE
            self.resp_dicts["msg"] = "所查找的文件不存在"
            return False, self.resp_dicts
        return True, self.resp_dicts

    rrq = RequestApiHelper.get_rrq()
    rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": oversea,
        "timeout": 30,
        "marks": marks,
        "proxy": proxy,
        "moths": MRequest.GET,
        "middler_list": [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares, rrq.marks_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    #
    # rrq.set_header(this_header).set_url(oversea) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.GET)

    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html, "url": oversea}
    return return_info.todict()


@router.post("/step9/down_ref")
async def down_ref(input: InputInfoModel[DataRefModel]):
    """
    20200923:
    下载引文 目前引文需要依赖题录下载的vl值;
    marks: 建议为 参考文献;
    year： 为年份，一般学校的 dbname=CJFDLAST+year 但api请求时uid 和year都是没有的，目前不要年依然可以成功;
    vl: vl为article请求后得到的，目前测试大概1小时左右有效;
    filename: 目前大小写无影响;
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    marks = input.data.marks
    proxy = input.proxy
    filename = input.data.filename
    year = input.data.year
    vl = input.data.vl
    uid = input.data.uid
    this_header = headers.copy()
    del this_header["Origin"]
    if filename[:4] in PYKM_LISTS:
        dbcode = "CCJD"
    else:
        dbcode = "CJFD"

    this_header[
        'Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
    this_header[
        'Referer'] = 'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=%s&filename=%s&dbname=CJFDLAST%s&uid=%s' % (
        dbcode, filename, year, uid)
    this_header['Host'] = 'kns.cnki.net'
    this_header['Sec-Fetch-Dest'] = 'iframe'

    url = r'https://kns.cnki.net/kcms/detail/frame/list.aspx?dbcode=%s&filename=%s&dbname=CJFDLAST%s&RefType=1&vl=%s' % (
        dbcode, filename.lower(), year, vl)

    def article_middlerwares(self):
        """
        验证返回码
        :return:
        """
        if self.html.find('未找到相关数据') != -1:
            self.resp_dicts["code"] = MsgCode.NO_RESOURCE
            self.resp_dicts["msg"] = "所查找的文件不存在"
            return False, self.resp_dicts
        return True, self.resp_dicts

    rrq = RequestApiHelper.get_rrq()
    rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "proxy": proxy,
        "moths": MRequest.GET,
        "middler_list": [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares,
                         rrq.marks_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    # rrq.set_header(this_header).set_url(url) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.GET)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html, "url": url}
    return return_info.todict()


@router.post("/step9/down_ref_page")
async def down_ref(input: InputInfoModel[DataRefPageModel]):
    """
    20200923:
    下载引文(翻页，不是第一页，翻页请求与第一页请求有所不同) 目前引文需要依赖题录下载的vl值;
    marks: 建议为 参考文献;
    year： 为年份，一般学校的 dbname=CJFDLAST+year 但api请求时uid 和year都是没有的，目前不要年依然可以成功;
    vl: vl为article请求后得到的，目前测试大概1小时左右有效;
    filename: 目前大小写无影响;
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    marks = input.data.marks
    proxy = input.proxy
    filename = input.data.filename
    year = input.data.year
    vl = input.data.vl
    uid = input.data.uid
    curdbcode = input.data.curdbcode
    page = input.data.page
    this_header = headers.copy()

    if filename[:4] in PYKM_LISTS:
        dbcode = "CCJD"
    else:
        dbcode = "CJFD"

    this_header[
        'Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9'
    this_header[
        'Referer'] = 'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=%s&filename=%s&dbname=CJFDLAST%s&uid=%s' % (
        dbcode, filename, year, uid)
    this_header['Host'] = 'kns.cnki.net'
    this_header['Sec-Fetch-Dest'] = 'iframe'
    url = r'https://kns.cnki.net/kcms/detail/frame/list.aspx?dbcode=%s&filename=%s&dbname=CJFDLAST%s&RefType=1&vl=%s&CurDBCode=%s&page=%s' % (
        dbcode, filename, year, vl, curdbcode, page)

    def article_middlerwares(self):
        """
        验证返回码
        :return:
        """
        if self.html.find('未找到相关数据') != -1:
            self.resp_dicts["code"] = MsgCode.NO_RESOURCE
            self.resp_dicts["msg"] = "所查找的文件不存在"
            return False, self.resp_dicts
        return True, self.resp_dicts

    rrq = RequestApiHelper.get_rrq()
    rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "proxy": proxy,
        "moths": MRequest.GET,
        "middler_list": [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares,
                         rrq.marks_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    # rrq.set_header(this_header).set_url(url) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.GET)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html, "url": url}
    return return_info.todict()


@router.post("/step10/down_cited_page")
async def down_cited(input: InputInfoModel[DataCitedPageModel]):
    """
    20201111:
    下载被引(翻页，不是第一页，翻页请求与第一页请求有所不同) 目前引文需要依赖题录下载的vl值;
    marks: 建议为 引证文献;
    year： 为年份，一般学校的 dbname=CJFDLAST+year 但api请求时uid 和year都是没有的，目前不要年依然可以成功;
    vl: vl为article请求后得到的，目前测试大概1小时左右有效;
    filename: 目前大小写无影响;
    :param input:
    :return:
    """
    return_info = ReturnInfo()
    marks = input.data.marks
    proxy = input.proxy
    filename = input.data.filename
    dbname = input.data.dbname
    vl = input.data.vl
    uid = input.data.uid
    curdbcode = input.data.curdbcode
    page = input.data.page
    this_header = headers.copy()
    if filename[:4] in PYKM_LISTS:
        dbcode = "CCJD"
    else:
        dbcode = "CJFD"
    this_header[
        'Referer'] = 'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=%s&filename=%s&dbname=%s&uid=%s' % (
        dbcode, filename, dbname, uid)
    this_header['Sec-Fetch-Dest'] = 'iframe'
    url = r'https://kns.cnki.net/kcms/detail/frame/list.aspx?dbcode=%s&filename=%s&dbname=%s&RefType=3&vl=%s&CurDBCode=%s&page=%s' % (
        dbcode, filename, dbname, vl, curdbcode, page)

    def article_middlerwares(self):
        """
        验证返回码
        :return:
        """
        if self.html.find('未找到相关数据') != -1:
            self.resp_dicts["code"] = MsgCode.NO_RESOURCE
            self.resp_dicts["msg"] = "所查找的文件不存在"
            return False, self.resp_dicts
        return True, self.resp_dicts

    rrq = RequestApiHelper.get_rrq()
    rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "proxy": proxy,
        "moths": MRequest.GET,
        "middler_list": [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares,
                         rrq.marks_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.article_middlerwares = types.MethodType(article_middlerwares, rrq)
    # rrq.set_header(this_header).set_url(url) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.have_end_middlerwares, rrq.article_middlerwares, rrq.marks_middlerwares])
    # bools, dicts = await rrq.run(MRequest.GET)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"html": rrq.html, "url": url}
    return return_info.todict()


@router.post("/step11/down_refcount")
async def down_refcount(input: InputInfoModel[DataArticleModel]):
    """
    下载引文数量信息，目前下载不依赖题录下载，但已经发现参数vl，不确认后面是否需要依赖
    marks 建议为 'REFERENCE'

    :param input:
    :return:
    """
    return_info = ReturnInfo()
    marks = input.data.marks
    proxy = input.proxy
    filename = input.data.filename
    this_header = headers.copy()
    if filename[:4] in PYKM_LISTS:
        dbcode = "CCJD"
    else:
        dbcode = "CJFD"
    this_header['Referer'] = r'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=%s&filename=%s' % (dbcode, filename)

    url = r'https://kns.cnki.net/kcms/detail/block/refcount.aspx?dbcode=%s&filename=%s&vl=' % (dbcode, filename)

    def on_request_end(self):
        if self.html:
            self.html = self.html.replace("'", '"')  # 单引号替换为双引号

    rrq = RequestApiHelper.get_rrq()
    rrq.on_request_end = types.MethodType(on_request_end, rrq)
    kwargs = {
        "rrq": rrq,
        "header": this_header,
        "url": url,
        "timeout": 30,
        "marks": marks,
        "proxy": proxy,
        "moths": MRequest.GET,
        "middler_list": [rrq.status_code_middlerwares, rrq.marks_middlerwares, rrq.is_json_middlerwares]
    }
    bools, dicts = await RequestApiHelper.etl_remote_meta(**kwargs)
    # rrq = AioHttpRequest()
    # rrq.on_request_end = types.MethodType(on_request_end, rrq)
    #
    # rrq.set_header(this_header).set_url(url) \
    #     .set_timeout(30).set_marks(marks) \
    #     .set_proxy(proxy) \
    #     .set_middler_list(
    #     [rrq.status_code_middlerwares, rrq.marks_middlerwares, rrq.is_json_middlerwares])
    # bools, dicts = await rrq.run(MRequest.GET)
    return_info.status = bools_string(bools)
    return_info.msg_code = dicts["code"]
    return_info.msg = dicts["msg"]
    return_info.data = {"jsons": rrq.html, "url": url}
    return return_info.todict()
